package com.example.personalaccount.controller;


import com.example.personalaccount.dto.ClauseDto;
import com.example.personalaccount.entity.Clause;
import com.example.personalaccount.repository.ClauseRepository;
import com.example.personalaccount.service.ClauseService;
import com.example.personalaccount.service.impl.ExcelExportService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping(value = "/clause")
@ResponseBody
@Tag(name = "账单管理")
public class ClauseController {
    @Autowired
    private ExcelExportService excelExportService;
    @Autowired
    private ClauseService clauseService ;


    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/search")
    @Operation(summary = "制定账户账单")
    public List<Clause> search(@RequestParam(required = false,defaultValue = "") String account, @RequestParam boolean flag)
    {
        List<Clause> clauses = clauseService.getClauseByAccountId("123123");
        List<Clause> result = new ArrayList<Clause>();
        for (Clause clause : clauses)
        {
            if (clause.getDestinationAccount().equals(account) || clause.getOriginAccount().equals(account) || account.equals("") && clause.isFlag()==flag)
            {
                result.add(clause);
            }
        }
        return result;
    }


    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/get/{id}")
    @Operation(summary = "获取账单")
    public Clause getClause(@PathVariable String id)
    {
        return clauseService.getClause(id);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/getAccount")
    @Operation(summary = "获取账户账单")
    public List<Clause> getClauseByAccount()
    {
        return clauseService.getClauseByAccountId("123123");
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/getDate")
    @Operation(summary = "获取日期账单")
    public List<Clause> getData(@RequestBody LocalDate date)
    {
        return clauseService.getClauseByDate(date);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/getPayFlag")
    @Operation(summary = "获取收支")
    public List<Clause> getData(@RequestBody Boolean flag)
    {
        return clauseService.getClauseByFlag(flag);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/getPayFunc/{func}")
    @Operation(summary = "获取方式")
    public List<Clause> getFunc(@PathVariable String func)
    {
        return clauseService.getClauseByFunc(func);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/create")
    @Operation(summary = "添加账单")
    public Clause create(@RequestBody ClauseDto clauseDto)
    {
        return clauseService.create(clauseDto);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/update")
    @Operation(summary = "更新账单")
    public Clause update(@RequestBody ClauseDto clauseDto)
    {
        return clauseService.create(clauseDto);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/date/{day}/{status}")
    @Operation(summary = "获取当月某日订单")
    public List<Clause> date(@PathVariable int day , @PathVariable boolean flag)
    {
        return clauseService.getClauseByDay(day,flag);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/date/{month}/{status}")
    @Operation(summary = "获取某月订单")
    public List<Clause> month(@PathVariable int month , @PathVariable boolean flag)
    {
        return clauseService.getClauseByMonth(month,flag);
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/date/{year}/{status}")
    @Operation(summary = "获取某年订单")
    public List<Clause> year(@PathVariable int year , @PathVariable boolean flag)
    {
        return clauseService.getClauseByYear(year,flag);
    }


    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @GetMapping("/range/{startTime}/{endtime}")
    @Operation(summary = "获取范围内的订单")
    public List<Clause> range(@PathVariable String startTime , @PathVariable String endtime)  // 输入格式 22-06-06 06:06:06
    {
        return clauseService.getClauseByRange(
                        LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("YY_MM_DD_HH_MM_SS")),
                        LocalDateTime.parse(endtime, DateTimeFormatter.ofPattern("YY_MM_DD_HH_MM_SS"))
                );
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/download")
    @Operation(summary = "导出订单")
    public ResponseEntity<byte[]> download(@RequestBody List<Clause> clauses)
    {
        try {
            byte[] excelFile = excelExportService.generateExcel(clauses);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "attachment; filename=账单信息.xlsx");
            return new ResponseEntity<>(excelFile, headers, HttpStatus.OK);
        } catch (IOException e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/echarts/{year}/{flag}")
    @Operation(summary = "统计图")
    public double[] chart(@PathVariable int year , @PathVariable boolean flag){
        double[] data = new double[13];
        for (Clause clause : clauseService.getClauseByYear(year, flag)) {
            data[clause.getTimeStamp().getMonthValue()] += clause.getAmount();
        }
        return data;
    }

    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @PostMapping("/del/{id}")
    @Operation(summary = "删除账单")
    public Boolean delete(@PathVariable String id ){
        Clause delete = clauseService.delete(id);
        if (delete != null)  return true ;
        else return false;
    }


}
